class Yoga {

    constructor(page) {
        this.page = new YogaElement(page);
        this.page.setChangeListener(()=>{
            this._onChangeListener();
        });
        this.page._element.onclick = (e) => {
            if (this.cElement) {
                this.cElement.setSelected(false);
                this.cElement = null;
            }
            e.cancelBubble = true;
        };
        this.cElement = null;
    }

    addElement(tagName) {
        var newElement = new YogaElement(document.createElement(tagName));
        newElement.setAssistStyle('min-height', '10px');
        newElement.setAssistStyle('min-width', '10px');
        newElement.setChangeListener(() => {
            this._onChangeListener();
        });
        newElement._element.draggable=true;
        newElement._element.onclick = (e) => {
            this.cElement = newElement;
            var el = this.selected(e.target);
            if (this._onElementSelected) {
                this._onElementSelected(el);
            }
            e.cancelBubble = true;
        };
        if (this.cElement) {
            this.cElement.addElement(newElement);
        } else {
            this.page.addElement(newElement);
        }
        return newElement;
    };

    selected(target) {
        var el;
        this.page.eachElement((element, level, parent) => {
            element.setSelected(target === element._element);
            if (target === element._element) {
                el = element;
            }
        });
        return el;
    }

    setOnElementSelected(f) {
        this._onElementSelected = f;
    }

    findElement(target) {
        if(this.page._element===target){
            return this.page;
        }
        return this.page.findElement(target);
        // var e;
        // this.page.eachElement((element, level, parent) => {
        //     if (element._element === target) {
        //         e = element;
        //     }
        // });
        // return e;
    }

    refreshElementTree() {
        var that = this;

        var labels = [];
        this.page.eachElement((element, level, parent) => {
            var label = document.createElement("label");
            label.style['text-indent'] = level + 'em';
            if (element === this.cElement) {
                label.style['color'] = 'red';
            }
            label.innerText = element.getElementType();
            label.onclick = function () {
                that.cElement = that.selected(element._element);
                if (that._onElementSelected) {
                    that._onElementSelected(element);
                }
            };
            labels.push(label);
        });
        return labels;
    };

    genJson() {
        return JSON.stringify(this.page);
    }

    setChangeListener(f) {
        this._changeListener = f;
    }

    _onChangeListener() {
        if (this._changeListener) {
            this._changeListener();
        }
    }
}


class YogaElement {
    constructor(e) {
        this._element = e;
        this._element.style['border'] = 'solid 1px lightgrey';
        this._element.onmouseover = (e) => {
            this._element.style['border'] = 'solid 1px black';
            e.cancelBubble = true;
        };
        this._element.onmouseleave = (e) => {
            if (!this.selected) {
                this._element.style['border'] = 'solid 1px lightgrey';
            }
            e.cancelBubble = true;
        };
        // this._children = [];
        this.selected = false;
        this.tagName = this._element.tagName.toLowerCase();
        // this.style = {};
    }

    /**
     * 获取元素类型
     */
    getElementType() {
        return this.tagName;
    }

    /**
     * 添加元素
     * @param el
     */
    addElement(el) {
        if (!this._children) {
            this._children = [];
        }
        this._children.push(el);
        this._element.appendChild(el._element);
        el.parent = this;
        this._onChangeListener();
    }

    /**
     * 移除元素
     * @param el
     */
    removeElement(el) {
        var index = this._children.indexOf(el);
        this._children.splice(index, 1);
        this._element.removeChild(el._element);
        this._onChangeListener();
    }

    /**
     * 寻找元素
     */
    findElement(el) {
        var item;
        this.eachElement(function (element, level, parent) {
            if (el === element || el === element._element) {
                item = element;
            }
        });
        return item;
    }

    /**
     * 设置辅助样式
     */
    setAssistStyle(name, value) {
        this._element.style[name] = value;
    }

    /**
     * 设置样式
     */
    setStyle(name, value) {
        this._element.style[name] = value;
        if (!this.style) {
            this.style = {};
        }
        this.style[name] = value;
        this._onChangeListener();
    }

    /**
     * 获取样式值
     */
    getStyleValue(name) {
        if (this.style && this.style[name]) {
            return this.style[name];
        }
        return undefined;
    }

    /**
     * 设置选中
     */
    setSelected(selected) {
        this.selected = selected;
        if (selected) {
            this._element.style['border'] = 'solid 1px black';
        } else {
            this._element.style['border'] = 'solid 1px lightgrey';
            if (this.style) {
                for (var key in this.style) {
                    this._element.style[key] = this.style[key];
                }
            }
        }
    }

    /**
     * 设置action
     */
    setAction(action) {
        this._action = action;
        this._onChangeListener();
    }

    /**
     * 获取action
     */
    getAction() {
        return this._action ? this._action : "";
    }

    /**
     * 设置改变监听
     */
    setChangeListener(f) {
        this._changeListener = f;
    }

    _onChangeListener() {
        if (this._changeListener) {
            this._changeListener();
        }
    }

    eachElement(callback) {
        this._eachChildElement(this,0, callback);
    }

    _eachChildElement(element, level, callback) {
        var children = element._children;
        if (children) {
            if (children.length > 0) {
                for (var i = 0; i < children.length; i++) {
                    var child = children[i];
                    if (callback) {
                        callback(child, level, element);
                    }
                    this._eachChildElement(child, level + 1, callback);
                }
            }
        }
    }

    toJSON() {
        return {
            tagName: this.tagName,
            style: this.style,
            children: this._children,
            action: this._action,
        }
    }
}








